查看原文
其他

扯一扯HTTPS单向认证、双向认证、抓包原理、反抓包策略

奶绿不加糖 伟伟学Python 2022-05-24

HTTP(HyperText Transfer Protocol,超文本传输协议)被用于在 Web 浏览器和网站服务器之间传递信息,在 TCP/IP 中处于应用层。这里提一下TCP/IP 的分层共分为四层:应用层、传输层、网络层、数据链路层;

分层的目的是:分层能够解耦,动态替换层内协议或组件


各个层包含的内容:

应用层:向用户提供应用服务时的通信活动(ftp、dns、http)

传输层:网络连接中两台计算机的数据传输(tcp、udp)

网络层:处理网络上流动的数据包,通过怎样的传输路径把数据包传送给对方(ip)

数据链路层:与硬件相关的网卡、设备驱动等等


然而 HTTP 也有明显的缺点:

1. 通信使用明文,内容可能被窃听

2. 不验证通信方的身份,因此有可能遭遇伪装

3. 无法证明报文的完整性,所以有可能遭到篡改


针对这些缺点,HTTPS 就登场了。HTTPS 中的 S 表示 SSL 或者 TLS,就是在原 HTTP 的基础上加上一层用于数据加密、解密、身份认证的安全层,即

HTTP + 加密 + 认证 + 完整性保护 = HTTPS 


加密方式的相关内容:对称加密和非对称加密。

1. 对称加密 : 加密和解密数据使用同一个密钥。这种加密方式的特点是速度很快,常见对称加密的算法有 AES;


2. 非对称加密: 加密和解密使用不同的密钥,这两个密钥形成有且仅有唯一的配对,叫公钥和私钥。数据用公钥加密后必须用私钥解密,数据用私钥加密后必须用公钥解密。一般来说私钥自己保留好,把公钥公开给别人(一般公钥不会单独出现,而是会写进证书中),让别人拿自己的公钥加密数据后发给自己,这样只有自己才能解密。 这种加密方式的特点是速度慢,CPU 开销大,常见非对称加密算法有 RSA。


CA证书的相关内容

CA证书是由 CA(Certification Authority)机构发布的数字证书。其内容包含:电子签证机关的信息、公钥用户信息、公钥签名和有效期。这里的公钥服务端的公钥,这里的签名是指:用hash散列函数计算公开的明文信息的信息摘要,然后采用 CA 的私钥对信息摘要进行加密,加密完的密文就是签名。

即:证书 =  公钥 + 签名 +申请者和颁发者的信息

客户端中因为在操作系统中就预置了 CA 的公钥,所以支持解密签名(因为签名是使用 CA 的私钥加密的)


有了这些预备知识后,就可以来看看 HTTPS 是如何怎么做到安全认证的。


HTTPS 单向认证

先来看看单向认证的过程:

从上图可以看出,服务端拥有一对非对称密钥:B_公钥和 B_私钥。详细过程如下:

(1)客户端发起 HTTPS 请求,将 SSL 协议版本的信息发送给服务端。


(2)服务端去 CA 机构申请来一份 CA 证书,在前面提过,证书里面有服务端公钥和签名。将 CA 证书发送给客户端


(3)客户端读取 CA 证书的明文信息,采用相同的 hash 散列函数计算得到信息摘要( hash 目的:验证防止内容被修改),然后用操作系统带的 CA 的公钥去解密签名(因为签名是用 CA 的私钥加密的),对比证书中的信息摘要。如果一致,则证明证书是可信的,然后取出了服务端公钥


(4)客户端生成一个随机数(密钥 F),用刚才等到的服务端 B_公钥 去加密这个随机数形成密文,发送给服务端。


(5)服务端用自己的 B_私钥 去解密这个密文,得到了密钥F


(6)服务端和客户端在后续通讯过程中就使用这个密钥 F 进行通信了。和之前的非对称加密不同,这里开始就是一种对称加密的方式


HTTPS 双向认证

双向认证和单向认证原理基本差不多,单向认证客户端需要认证服务端,而在双向认证中增加了服务端对客户端的认证。

双向认证详细过程如下(与单向认证的不同点用橙色标注来):

(1)客户端发起 HTTPS 请求,将 SSL 协议版本的信息发送给服务端。


(2)服务端去 CA 机构申请来一份 CA 证书,在前面提过,证书里面有服务端公钥和签名。然后将 CA 证书发送给客户端


(3)客户端读取 CA 证书的明文信息,采用相同的 hash 散列函数计算得到信息摘要(hash 目的:验证防止内容被修改),然后用操作系统带的 CA 的公钥去解密签名(因为签名是用 CA 的私钥加密的),对比证书中的信息摘要。如果一致,则证明证书是可信的,然后取出了服务端公钥


(4)客户端发送自己的客户端证书给服务端,证书里面有客户端的公钥:C_公钥


(5)客户端发送支持的对称加密方案给服务端,供其选择


(6)服务端选择完加密方案后,用刚才得到的 C_公钥 去加密选好的加密方案


(7)客户端用自己的 C_私钥 去解密选好的加密方案,客户端生成一个随机数(密钥 F),用刚才等到的服务端 B_公钥 去加密这个随机数形成密文,发送给服务端。


(8)服务端和客户端在后续通讯过程中就使用这个密钥 F 进行通信了。和之前的非对称加密不同,这里开始就是一种对称加密的方式


HTTPS 基本思路总结

HTTPS 在保证数据安全传输上使用对称加密和非对称加密相结合的方式来进行的,简单来说就是通过一次非对称加密算法进行了最终通信密钥的生成、确认和交换,然后在后续的通信过程中使用最终通信密钥进行对称加密通信。之所以不是全程非对称加密,是因为非对称加密的计算量大,影响通信效率。


抓包原理

HTTPS 即使安全,也是能够被抓包的,常见的抓包工具有:Charles、fildder 等。


常用的 HTTPS 抓包方式是作为中间人,对客户端伪装成服务端,对服务端伪装成客户端。简单来说:


  • 截获客户端的 HTTPS 请求,伪装成中间人客户端去向服务端发送HTTPS 请求


  • 接受服务端返回,用自己的证书伪装成中间人服务端向客户端发送

    数据内容。


具体过程如下图所示:


反抓包策略

为了防止中间人攻击,可以使用 SSL-Pinning 的技术来反抓包。

可以发现中间人攻击的要点的伪造了一个假的服务端证书给了客户端,客户端误以为真。解决思路就是,客户端也预置一份服务端的证书,比较一下就知道真假了。


SSL-Pinning有两种方式: 证书锁定(Certificate Pinning) 和公钥锁定( Public Key Pinning)。


  • 证书锁定

需要在客户端代码内置仅接受指定域名的证书,而不接受操作系统或浏览器内置的 CA 根证书对应的任何证书,通过这种授权方式,保障了客户端与服务端通信的唯一性和安全性,因此客户端与服务端(例如 API 网关)之间的通信是可以保证绝对安全。但是 CA 签发证书都存在有效期问题,缺点是在 证书续期后需要将证书重新内置到APP中


  • 公钥锁定

提取证书中的公钥并内置到客户端中,通过与服务器对比公钥值来验证连接的正确性。制作证书密钥时,公钥在证书的续期前后都可以保持不变(即密钥对不变),所以可以避免证书有效期问题,一般推荐这种做法。


突破SSL-Pinning抓包

在逆向界,一山更比一山高。

思路是这样的:内置证书或者公钥的时候,常常会有对比验证的函数,直接控制这个函数的返回结果让验证通过不就好了吗。

于是就有了一个突破 SLL-Pinning 的经典操作:采用 Xposed+justTrustMe模块。

这个方案使用的是 JustTrustMe 这个 Xposed 模块,它所做的事情就是将各种已知的的HTTP请求库中用于校验证书的 API 都进行 Hook,使无论是否是可信证书的情况,校验结果返回都为正常状态,从而实现绕过证书检查的效果。

更多突破 SSL-Pinning 进行抓包的方法请参考:

当你写爬虫抓不到APP请求包的时候该怎么办?【中级篇】(https://zhuanlan.zhihu.com/p/60392573)


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存